//============================================================================
// Name        : DiseñoII.cpp
// Author      : Daniel Rodriguez, Daniela Velasquez
// Version     :
// Copyright   : 
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include <stdlib.h>
#include "main.h"
#include <stdio.h>

using namespace std;

void disturb(Solution *s) {

}

/*Se deciden las ciudades a intercambiar*/
list<int*> findNeighbors(Solution *sact) {

	int i, j;
	int* mov; //= (int*) malloc(sizeof(int)*2);

	list<int*> vecinos;

	for (i = 0; i < sact->cityNumber; i++){
		for (j = i + 1; j < sact->cityNumber; j++) {
			mov = (int*) malloc(sizeof(int)*2);
			mov[0] = i;
			mov[1] = j;
			vecinos.push_back(mov);

		}
	}
	return vecinos;
}

Solution *initialSolution(list<Node> listaNodos) {

	Solution *is = new Solution(listaNodos.size());
	int i = 0;

	list<Node>::iterator iter = listaNodos.begin();

	while (iter != listaNodos.end()) {
		is->tour[i] =  *iter;
		if (i > 0){
				is->C[(is->tour[i - 1].nombre)-1][(is->tour[i].nombre)-1] = is->tour[i - 1].distanciaEuc(is->tour[i]);
				is->cost += is->C[(is->tour[i - 1].nombre)-1][(is->tour[i].nombre )-1];

	    }
		iter++;
		i++;
	}
	 	return is;
}

/**
 * Aplica busqueda local a una solucion inicial.
 * @param: un apuntador a una solucion inicial.
 * @return: un optimo local.
 */
Solution* localSearch(Solution *is) {

	Solution *sact = is;
	Solution *sP;
	list<int*> neighbors;

	neighbors = findNeighbors(sact);
	int i =0;

	while (!neighbors.empty() && i<10000) {

		int* chosen = neighbors.front();
	    neighbors.pop_front();
		sP = sact->swap(chosen[0], chosen[1]);

		if (sP->cost < sact->cost) {
			sact = sP;
			neighbors.clear();
			neighbors = findNeighbors(sact);
		}
		i++;
	}
	return sact;
}

/*
 Solution* ILocalSearch(list<Node> listaNodos){

 Solution *sact = initialSolution(listaNodos);
 Solution *sE = localSearch(listaNodos,sact);
 Solution *sMejor;

 while(criterio de Parada: op1: num iteraciones){

 //Solution *sP = disturb(sE);
 Solution *sPE = localSearch(listaNodos,sP);

 /*Criterio de Aceptacion
 //Mejor Mejor
 if(sP->cost > sPE->cost) sP = sPE;



 if(sMejor->cost > sP->cost) sMejor = sP;
 }

 return sMejor;
 }*/

int main(int argc, char* argv[]) {

	list<Node> nodelst;

	if (argc > 1) {
		Parser psr = Parser();
		nodelst = psr.leerArchivo(argv[1]);
	} else
		cout << "Falta la ruta del archivo .tsp" << endl;

	Solution *s = initialSolution(nodelst);
	Solution *sOpt = localSearch(s);

	sOpt->print();

	cout << endl << endl << "termino" << endl;
    return 0;
}
